package com.agou.core.util;

import java.text.DecimalFormat;

public class UtFormat {

	private static final double[][] mdDoublePrecision = {
		{ // 必须从小往大排
		10D, 0.0000001D }, { 100D, 0.0000001D }, { 1000D, 0.0000001D },
		{ 10000D, 0.0000001D }, { 100000D, 0.0000001D },
		{ 1000000D, 0.0000001D }, { 10000000D, 0.0000001D },
		{ 100000000D, 0.0000001D }, { 1000000000D, 0.0000001D },
		{ 10000000000D, 0.000001D }, { 100000000000D, 0.00001D },
		{ 1000000000000D, 0.0001D }, { 10000000000000D, 0.001D },
		{ 100000000000000D, 0.01D }, { 1000000000000000D, 0.1D } };
	/**
	 * 小写金额转换为大写金额 返回的大写金额自动加上了货币单位(固定为: '元'、'角'、'分') 适用区间：0.01 <=目标数字
	 * <100,000,000,000,000.00
	 */
	public static String toCaption(double dObjNumber) {
		/** 用于拆分数字的分母 */
		double dDenominator = 1000000000000000.00;
		String[] straNum = { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
		String[] straBit = { "仟", "佰", "拾", "万", "仟", "佰", "拾", "亿", "仟", "佰",
				"拾", "万", "仟", "佰", "拾", "元", "角", "分" };
		String[] straTmp = new String[40];
		String[] straObjNum = new String[40];
		double dTmpQuotient = 0;
		int[] naObjNum = new int[20];
		int nCounterI = 0;
		int nCounterJ = 0;
		int nCounterM = 0;
		int nObjLen = 0;
		double dDeno = dDenominator; // 2002/3/19Leixin: 代替dDenominator变量
		StringBuffer strbTmp = new StringBuffer("");

		/** 私有大写数字变量 */
		String strNoCaption;

		if (dObjNumber == 0) {
			// 若目标数字等于零
			strNoCaption = "零元整";
		} else { // 若目标数字不等于零
			dObjNumber = dObjNumber * 100; // 消除小数点

			while (dDeno >= 1) { // 逐步降低分母值
				dTmpQuotient = dObjNumber / dDeno;
				if (dTmpQuotient >= 1) {
					break;
				}
				dDeno = dDeno / 10;
			}
			nCounterI = 0;
			while (dDeno >= 1) { // 拆分数字，存为数组
				dTmpQuotient = dObjNumber / dDeno; // 取商
				naObjNum[nCounterI] = (int) (dTmpQuotient);
				dObjNumber = dObjNumber % dDeno;
				dDeno = dDeno / 10;
				nCounterI++;
			}
			nObjLen = nCounterI;
			nCounterJ = (nObjLen * 2 - 1);
			nCounterM = 17;
			for (nCounterI = nObjLen - 1; nCounterI >= 0; nCounterI--) { // 从最后一个数字开始循环
				straTmp[nCounterJ] = straBit[nCounterM];
				nCounterJ--;
				straTmp[nCounterJ] = straNum[naObjNum[nCounterI]]; // 替换为大写
				nCounterJ--;
				nCounterM--;
			}
			nObjLen = nObjLen * 2;
			nCounterJ = 0;
			nCounterM = 0;
			for (nCounterI = 0; nCounterI < nObjLen; nCounterI++) { // 删除多余的字符
				if (straTmp[nCounterI].compareTo("零") == 0) {
					if (straTmp[nCounterI + 1] != null) {
						if ((straTmp[nCounterI + 1].compareTo("万") != 0)
								&& (straTmp[nCounterI + 1].compareTo("亿") != 0)
								&& (straTmp[nCounterI + 1].compareTo("元") != 0)) {
							straObjNum[nCounterJ] = straTmp[nCounterI];
							nCounterI++;
							nCounterJ++;
							continue;
						} else {
							nCounterI++; // 保留"亿","万","元"
							straObjNum[nCounterJ] = straTmp[nCounterI];
							nCounterJ++;
							continue;
						}
					}
				} else {
					straObjNum[nCounterJ] = straTmp[nCounterI];
					nCounterJ++;
				}
			}
			nCounterJ = 0;
			while (straObjNum[nCounterJ] != null) { // 消除"亿","万","元"前的"零"字
				if (straObjNum[nCounterJ].compareTo("零") == 0) {
					if (straObjNum[nCounterJ + 1] != null) {
						if ((straObjNum[nCounterJ + 1].compareTo("万") == 0)
								|| (straObjNum[nCounterJ + 1].compareTo("亿") == 0)
								|| (straObjNum[nCounterJ + 1].compareTo("元") == 0)
								|| (straObjNum[nCounterJ + 1].compareTo("零") == 0)) {
							straObjNum[nCounterJ] = "_";
						}
					}
				}
				nCounterJ++;
			}
			if (straObjNum[nCounterJ - 1].compareTo("零") == 0) {
				// 消除最后的"零"字
				straObjNum[nCounterJ - 1] = "_";
			}
			nCounterJ = 0;
			nCounterI = 0;
			while (straObjNum[nCounterJ] != null) { // 消除所有"_"符号
				if (straObjNum[nCounterJ].compareTo("_") != 0) {
					straTmp[nCounterI] = straObjNum[nCounterJ];
					nCounterI++;
				}
				nCounterJ++;
			}
			nObjLen = nCounterI;
			for (nCounterI = 0; nCounterI < nObjLen; nCounterI++) { // 消除"亿"后的"万"字
				strbTmp.append(straTmp[nCounterI]);
				if ((straTmp[nCounterI].compareTo("亿") == 0)
						&& (straTmp[nCounterI + 1].compareTo("万") == 0)) {
					straTmp[nCounterI + 1] = "";
				}
			}
			strNoCaption = strbTmp.append("整").toString();
		}
		return strNoCaption;
	}

	/**
	 * 格式化数字 [例] format=“000” format("000",51) 返回值：051
	 * 
	 */
	public static String formatNumber(String format, long number) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(number);
	}

	/**
	 * 格式化数字 如果要求为3位整数，2位小数，那么format就是“000.00”
	 */
	public static String formatNumber(String format, double number) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(number);
	}

	/**
	 * 返回某个double型数值按指定位数四舍五入后的数值.
	 * 
	 * <pre>
	 * 四舍五入的例子: d = UtFormat.round(2.15, 1); // 将 2.15 四舍五入到一个小数位 (d = 2.2)
	 * d = UtFormat.round(2.149, 1); // 将 2.149 四舍五入到一个小数位 (d = 2.1)
	 * d = UtFormat.round(-1.475, 2); // 将 -1.475 四舍五入到两小数位 (d = -1.48)
	 * d = UtFormat.round(21.5, -1); // 将 21.5 四舍五入到小数点左侧一位 (d = 20)
	 * 
	 * </pre>
	 * 
	 * @param value
	 *            待处理的数值
	 * @param num_digits
	 *            位数
	 *            <ul>
	 *            <li>如果 num_digits 大于 0，则四舍五入到指定的小数位
	 *            <li>如果 num_digits 等于 0，则四舍五入到最接近的整数
	 *            <li>如果 num_digits 小于 0，则在小数点左侧进行四舍五入
	 *            </ul>
	 * @return 四舍五入的结果
	 */
	public static double round(double value, int num_digits) {
		int i = 0;
		for (i = 0; i < mdDoublePrecision.length; i++) {
			if (value > -mdDoublePrecision[i][0]
					&& value < mdDoublePrecision[i][0]) {
				break;
			}
		}
		if (i == 0 && Math.abs(value) < mdDoublePrecision[0][1]) {
			return 0;
		}

		if (i >= mdDoublePrecision.length) {
			throw new IllegalStateException("待处理的数值（value=#0）超过了系统处理能力,处理的值是：" + value);
		}

		if (value > 0) {
			value += mdDoublePrecision[i][1];
		} else {
			value -= mdDoublePrecision[i][1];
		}

		if (num_digits == 0) {
			value = Math.round(value);
		} else if (num_digits > 0) {
			value *= Math.pow(10, num_digits);
			value = Math.round(value);
			value /= Math.pow(10, num_digits);
		} else { // num_digits < 0
			value /= Math.pow(10, -num_digits);
			value = Math.round(value);
			value *= Math.pow(10, -num_digits);
		}

		return value;
	}

	/**
	 * 返回某个double型数值按指定位数截位后的数值.
	 * 
	 * <pre>
	 * 截位的例子: d = UtFormat.rint(2.15, 1); // 将 2.15 截位到一个小数位 (d = 2.1)
	 * d = UtFormat.rint(2.149, 1); // 将 2.149 截位到一个小数位 (d = 2.1)
	 * d = UtFormat.rint(-1.475, 2); // 将 -1.475 截位到两小数位 (d = -1.47)
	 * d = UtFormat.rint(21.5, -1); // 将 21.5 截位到小数点左侧一位 (d = 20)
	 * 
	 * </pre>
	 * 
	 * @param value
	 *            待处理的数值
	 * @param num_digits
	 *            位数
	 *            <ul>
	 *            <li>如果 num_digits 大于 0，则截位到指定的小数位
	 *            <li>如果 num_digits 等于 0，则截位到最接近的整数
	 *            <li>如果 num_digits 小于 0，则在小数点左侧进行截位
	 *            </ul>
	 * @return 截位的结果
	 */
	public static double rint(double value, int num_digits) {
		int i = 0;
		for (i = 0; i < mdDoublePrecision.length; i++) {
			if (value > -mdDoublePrecision[i][0]
					&& value < mdDoublePrecision[i][0]) {
				break;
			}
		}
		if (i == 0 && Math.abs(value) < mdDoublePrecision[0][1]) {
			return 0;
		}

		if (i >= mdDoublePrecision.length) {
			throw new IllegalStateException("待处理的数值（value=#0）超过了系统处理能力,处理的值是：" + value);
		}

		if (value > 0) {
			value += mdDoublePrecision[i][1];
		} else {
			value -= mdDoublePrecision[i][1];
		}

		if (num_digits == 0) {
			value = (long) value;
		} else if (num_digits > 0) {
			value *= Math.pow(10, num_digits);
			value = (long) value;
			value /= Math.pow(10, num_digits);
		} else { // num_digits < 0
			value /= Math.pow(10, -num_digits);
			value = (long) value;
			value *= Math.pow(10, -num_digits);
		}
		return value;
	}

	/**
	 * 返回某个double型数值取整后的数值.
	 * 
	 * <pre>
	 * 取整的例子: l = UtFormat.rint(2.15); // 将 2.15 取整 (l = 2)
	 * l = UtFormat.rint(2.149); // 将 2.149 取整 (l = 2)
	 * l = UtFormat.rint(-1.475); // 将 -1.475 取整 (l = -1)
	 * l = UtFormat.rint(21.5); // 将 21.5 取整 (l = 21)
	 * 
	 * </pre>
	 * 
	 * @param value
	 *            待处理的数值
	 * @return 取整的结果
	 */
	public static long rint(double value) {
		int i = 0;
		for (i = 0; i < mdDoublePrecision.length; i++) {
			if (value > -mdDoublePrecision[i][0]
					&& value < mdDoublePrecision[i][0]) {
				break;
			}
		}
		if (i == 0 && Math.abs(value) < mdDoublePrecision[0][1]) {
			return 0;
		}

		if (i >= mdDoublePrecision.length) {
			throw new IllegalStateException("待处理的数值（value=#0）超过了系统处理能力,处理的值是：" + value);
		}

		if (value > 0) {
			value += mdDoublePrecision[i][1];
		} else {
			value -= mdDoublePrecision[i][1];
		}

		return (long) value;
	}
	
	public static final String format(String msg, Object... args) {
		if (msg != null && msg.length() > 0 && msg.indexOf('#') > -1) {
			StringBuilder sb = new StringBuilder();
			boolean isArg = false;
			for (int x = 0; x < msg.length(); x++) {
				char c = msg.charAt(x);
				if (isArg) {
					isArg = false;
					if (Character.isDigit(c)) {
						int val = Character.getNumericValue(c);
						if (val >= 0 && val < args.length) {
							sb.append(args[val]);
							continue;
						}
					}
					sb.append('#');
				}
				if (c == '#') {
					isArg = true;
					continue;
				}
				sb.append(c);
			}

			if (isArg) {
				sb.append('#');
			}
			return sb.toString();
		}
		return msg;

	}

}
